﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SuperKit {
    class KDraw {
        public static readonly Color _rowBackColor1 = Color.White;
        public static readonly Color _rowBackColor2 = Color.FromArgb(254, 216, 249);
        public static readonly Color _selectedColor = Color.FromArgb(75, 188, 254);
        public static readonly Color _headColor = Color.FromArgb(75, 188, 254);
        public static readonly Color _borderColor = Color.FromArgb(55, 126, 168);

        public static void DrawSelectedBackground(Graphics g, Rectangle rect, Color baseColor, Color borderColor) {
            Color innerBorderColor = Color.FromArgb(150, 255, 255, 255);

            RenderBackgroundInternal(g, rect, baseColor, borderColor,
                innerBorderColor, 0.45f, true, LinearGradientMode.Vertical);
        }

        public static void DrawSelectedBackground(Graphics g, Rectangle rect) {
            Color baseColor = _selectedColor;
            Color borderColor = _selectedColor;
            Color innerBorderColor = Color.FromArgb(150, 255, 255, 255);

            RenderBackgroundInternal(g, rect, baseColor, borderColor, 
                innerBorderColor, 0.45f, true, LinearGradientMode.Vertical);
        }

        internal static void RenderBackgroundInternal(Graphics g, Rectangle rect, Color baseColor, Color borderColor,
            Color innerBorderColor, float basePosition, bool drawBorder, LinearGradientMode mode) {
            if (drawBorder) {
                rect.Width--;
                rect.Height--;
            }

            if (rect.Width <= 0 || rect.Height <= 0) {
                return;
            }

            using (LinearGradientBrush brush = new LinearGradientBrush(
               rect, Color.Transparent, Color.Transparent, mode)) {
                Color[] colors = new Color[4];
                colors[0] = GetColor(baseColor, 0, 35, 24, 9);
                colors[1] = GetColor(baseColor, 0, 13, 8, 3);
                colors[2] = baseColor;
                colors[3] = GetColor(baseColor, 0, 68, 69, 54);

                ColorBlend blend = new ColorBlend();
                blend.Positions = new float[] {
                    0.0f, basePosition, basePosition + 0.05f, 1.0f };
                blend.Colors = colors;
                brush.InterpolationColors = blend;
                g.FillRectangle(brush, rect);
            }
            if (baseColor.A > 80) {
                Rectangle rectTop = rect;
                if (mode == LinearGradientMode.Vertical) {
                    rectTop.Height = (int)(rectTop.Height * basePosition);
                } else {
                    rectTop.Width = (int)(rect.Width * basePosition);
                }
                using (SolidBrush brushAlpha =
                    new SolidBrush(Color.FromArgb(80, 255, 255, 255))) {
                    g.FillRectangle(brushAlpha, rectTop);
                }
            }

            if (drawBorder) {
                using (Pen pen = new Pen(borderColor)) {
                    g.DrawRectangle(pen, rect);
                }

                rect.Inflate(-1, -1);
                using (Pen pen = new Pen(innerBorderColor)) {
                    g.DrawRectangle(pen, rect);
                }
            }
        }

        public static Color GetColor(Color colorBase, int a, int r, int g, int b) {
            int a0 = colorBase.A;
            int r0 = colorBase.R;
            int g0 = colorBase.G;
            int b0 = colorBase.B;

            if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
            if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
            if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
            if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }

            return Color.FromArgb(a, r, g, b);
        }



        public static GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int cornerRadius) {
            GraphicsPath roundedRect = new GraphicsPath();
            roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
            roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
            roundedRect.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);
            roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
            roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom);
            roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
            roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);
            roundedRect.CloseFigure();
            return roundedRect;
        }
        public static void DrawRoundRectangle(Graphics g, Pen pen, Rectangle rect, int cornerRadius) {
            using (GraphicsPath path = CreateRoundedRectanglePath(rect, cornerRadius)) {
                g.DrawPath(pen, path);
            }
        }
        public static void FillRoundRectangle(Graphics g, Brush brush, Rectangle rect, int cornerRadius) {
            using (GraphicsPath path = CreateRoundedRectanglePath(rect, cornerRadius)) {
                g.FillPath(brush, path);
            }
        }
    }
}
